#pragma once

#include "bezier.h"
#include "poly_bezier_builder_base.h"
#include <imglib/image.h>

namespace outline {

typedef index_vector_type area_type;
typedef area_type const * area_cptr_type;
typedef std::vector<area_cptr_type> area_cptr_vector_type;

template <typename T, typename R = typename type_traits<T>::real_type>
class guided_poly_bezier_builder : public poly_bezier_builder_base<T, R>
{
public:
	typedef poly_bezier_builder_params<R> params_type;
public:
	void clear();
	void reset(nodes_type const & polyline, 
		area_cptr_vector_type const & areas, std::vector<junc_type> const & junc);
	void set_params(params_type const & params);
	void inspect_all_pieces();
	uint area_size(uint a) { return areas_[a]->size(); }
public:
	virtual R select_best(index_vector_type & ivec);
	virtual params_type const & get_params() const
		{ return params_; }
	virtual estimation_type const & get_estimation(uint begin, uint len, uint piece_num) const;
	virtual void get_junction_types(index_vector_type const & ivec, std::vector<junc_type> & junc) const;
private:
	params_type params_;
	area_cptr_vector_type areas_;
	std::vector<junc_type> junc_;

	typedef img::simple_image<estimation_type> estimation_image_type;

	typedef std::vector<estimation_image_type> all_estimations_type;
	/// all_estimations_[i][k][l].d tell the approximation discrepancy of piece between
	/// nodes_[area[i].k] and nodes_[area[i+1].l], for the piece that can't be approximated null is reported
	all_estimations_type all_estimations_;

	/// next_image[k][l] tells what is the next node (in the next area) for the
	/// start at node k in some known area and finish at node l at another known area
	typedef img::image<uint> next_image_type;
	typedef std::vector<next_image_type> nexts_type;
private:
	// next_images are created for each arrea except the last, routes are from beginning area to the last area
	void select_best_open_core(nexts_type & nexts, estimation_image_type & routes);
};

} //namespace outline
